﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Common.CipherTextHelper
{
    public class CipherTextHelper
    {
        /// <summary>
        /// 计算文本的Md5值
        /// </summary>
        /// <param name="txt">文本</param>
        /// <param name="encoding">编码类型(默认为UTF8)</param>
        /// <param name="isUpper">字符串是否大写(默认小写)</param>
        /// <returns></returns>
        public static string GetMd5(string txt, Encoding encoding, bool isUpper = false)
        {
            var md5 = MD5.Create();
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            var buffer = encoding.GetBytes(txt);
            var md5Buffer = md5.ComputeHash(buffer);
            var rule = isUpper ? "X2" : "x2";
            var sb = new StringBuilder();

            foreach (var t in md5Buffer)
            {
                sb.Append(t.ToString(rule));
            }
            return sb.ToString();
        }

        /// <summary>
        ///  计算文件的Md5值
        /// </summary>
        /// <param name="fileStream">文件流</param>
        /// <returns></returns>
        public static string GetFileMd5(Stream fileStream)
        {
            using var oMd5Hasher = new MD5CryptoServiceProvider();
            var arrByteHashValue = oMd5Hasher.ComputeHash(fileStream);

            //由以连字符分隔的十六进制对构成的String，其中每一对表示value 中对应的元素；例如“F-2C-4A”

            var strHashData = System.BitConverter.ToString(arrByteHashValue);

            //替换-
            return strHashData.Replace("-", "");

        }

        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="str">需要加密的字符串</param>
        /// <param name="key">秘钥</param>
        /// <returns></returns>
        public static string DesEncrypt(string str, string key)
        {
            var keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
            var keyIv = Encoding.UTF8.GetBytes(key.Substring(key.Length - 8, 8)); ;
            var inputByteArray = Encoding.UTF8.GetBytes(str);
            using var provider = new DESCryptoServiceProvider();
            using var mStream = new MemoryStream();
            using var cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIv), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());
        }

        /// <summary>
        /// Des解密
        /// </summary>
        /// <param name="str">需要解密的字符串</param>
        /// <param name="key">秘钥</param>
        /// <returns></returns>
        public static string DesDecrypt(string str, string key)
        {

            var keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
            var keyIv = Encoding.UTF8.GetBytes(key.Substring(key.Length - 8, 8)); ;
            var inputByteArray = Convert.FromBase64String(str);
            using var provider = new DESCryptoServiceProvider();
            using var mStream = new MemoryStream();
            using var cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIv), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());
        }

        /// <summary>
        /// Base64编码
        /// </summary>
        /// <param name="encoding">编码类型(默认为UTF8)</param>
        /// <param name="str">需要编码的字符串</param>
        /// <returns></returns>
        public static string EncodeBase64(Encoding encoding, string str)
        {

            var bytes = encoding.GetBytes(str);

            try
            {
                return Convert.ToBase64String(bytes);
            }
            catch
            {
                return str;
            }
        }

        /// <summary>
        /// Base64解码
        /// </summary>
        /// <param name="encoding">编码类型(默认为UTF8)</param>
        /// <param name="str">需要解码的字符串</param>
        /// <returns></returns>
        public static string DecodeBase64(Encoding encoding, string str)
        {

            var bytes = Convert.FromBase64String(str);
            try
            {
                return encoding.GetString(bytes);
            }
            catch
            {
                return str;
            }
        }

    }
}